﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DCS.Business.Interface;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System.Configuration;
using DCS.DataProvider;
using DCS.Business.Manager;
using DCS.Business.Model;
using System.Data.SqlClient;
using CarolLib;
using DCS.DemoWinApp.TMPP_PRL_Interface_WS;
using System.Text.RegularExpressions;


namespace DemoWinApp1
{
	public class FlightComparer : IEqualityComparer<Flight_Type>
	{
		bool IEqualityComparer<Flight_Type>.Equals(Flight_Type x, Flight_Type y)
		{
			return x.DepartureDate == y.DepartureDate
				&& x.FlightNumber == y.FlightNumber
				&& x.DepartureAirport == y.DepartureAirport
				&& x.FNPostfix == y.FNPostfix;
		}

		int IEqualityComparer<Flight_Type>.GetHashCode(Flight_Type obj)
		{
			return 0;
		}
	}

	public class PRLSyncer : IMessageSyncer
	{
		static log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);


		public void Init()
		{
			//IUnityContainer myContainer = new UnityContainer();
			//UnityConfigurationSection section
			//  = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
			//section.Containers["Data"].Configure(myContainer);

			//IDataProvider dp = myContainer.Resolve<IDataProvider>();

			//DCSmanager = new DCSFileManager(dp);
			//PRLManager = new PRLMessageManager(dp);

			connectionString = ConfigurationManager.ConnectionStrings["DCSDB"].ConnectionString;
		}



		public void DetectAndSync()
		{
            //List<PRLMessage> PRLMessageList = null;
            //List<DCSFile> DCSFileList = null;
            //List<int> syncSuccessFileIds = new List<int>();

            //using (SqlConnection conn = GetSqlConnection())
            //{
            //    //string sqlquery = "SELECT TOP 300 * FROM [dbo].[PRLMessage] WHERE ShareCode! = '' ORDER BY RefFileId DESC ";
            //    using (SqlDataReader dr = SqlHelper.ExecuteReader(conn, "up_GetSyncMessagesByMessageType",
            //            new SqlParameter("@MessageType", "PRL"),
            //            new SqlParameter("@GroupCount", 100)
            //        ))
            //    {
            //        PRLMessageList = DTOHelper.CreateModelList<PRLMessage>(dr);
            //        if (dr.NextResult())
            //        {
            //            DCSFileList = DTOHelper.CreateModelList<DCSFile>(dr);


            //        }
            //    }

            //    IEnumerable<IGrouping<string, IEnumerable<PRLMessage>>> remoteFileNameAndFileIds = DCSFileList.GroupBy<DCSFile, string, IEnumerable<PRLMessage>>(f => f.RemoteFileName.Substring(0, 19), f => PRLMessageList.Where(p => p.RefFileId == f.FileId));

            //    //sqlquery = "SELECT SUBSTRING([RemoteFileName],0,19),*,num FROM ( SELECT *, RANK() OVER(PARTITION BY SUBSTRING([RemoteFileName],0,19) ORDER BY [RemoteFileName]) num FROM [DCSDownloadCenterDB].[dbo].[DCSFile] WHERE [RemotePath] = '/PRL/' ) X WHERE num = 1";
            //    //using (SqlDataReader dr = SqlHelper.ExecuteReader(conn, sqlquery, System.Data.CommandType.Text))
            //    //{
            //    //    DCSFileList = DTOHelper.CreateModelList<DCSFile>(dr);
            //    //}
            //}


            //IEnumerable<IGrouping<Flight_Type, PRLMessage>> prlFlightGroups = PRLMessageList.GroupBy(p => new Flight_Type
            //{
            //    DepartureDate = p.PDate,
            //    FlightNumber = p.Carrier + p.FlightNo,
            //    DepartureAirport = p.DeptAirport,
            //    FNPostfix = "",
            //}, new FlightComparer());

            //int snFix = 1;
            //foreach (IGrouping<Flight_Type, PRLMessage> prlFlightGroup in prlFlightGroups)
            //{
            //    ESBTMPPPRLService1 esbService = new ESBTMPPPRLService1();
            //    PRLMessage_Type prlmessage = new PRLMessage_Type();
            //    esbService.PRLMessage = prlmessage;
            //    prlmessage.Flight = prlFlightGroup.Key;

            //    IEnumerable<IGrouping<string, PRLMessage>> prlFlightCabinNoGroups = prlFlightGroup.GroupBy(p => p.CabinNo);
            //    ICollection<CategoryBySegmentAndCarbin_Type> categories = new List<CategoryBySegmentAndCarbin_Type>();
            //    #region category
            //    foreach (IGrouping<string, PRLMessage> prlFlightCabinNoGroup in prlFlightCabinNoGroups)
            //    {
            //        CategoryBySegmentAndCarbin_Type category = new CategoryBySegmentAndCarbin_Type();
            //        categories.Add(category);
            //        ICollection<Passenger_Type> passengers = new List<Passenger_Type>();
            //        #region passenger
            //        foreach (PRLMessage prl in prlFlightCabinNoGroup)
            //        {
            //            Passenger_Type passenger = new Passenger_Type();
            //            passengers.Add(passenger);
            //            BaggageInfo_Type baggage = new BaggageInfo_Type();
            //            passenger.BaggageInfo = baggage;
            //            baggage.BaggagePieces = string.IsNullOrEmpty(prl.WK) ? 0 : int.Parse(prl.WK.Split('/')[1]);
            //            baggage.BaggageWeight = string.IsNullOrEmpty(prl.WK) ? 0 : int.Parse(prl.WK.Split('/')[2]);
            //            baggage.WeightUnit = "K";
            //            string[] packages = prl.Package.Trim().Split(new char[] { '\x20' }, StringSplitOptions.RemoveEmptyEntries);

            //            passenger.BaggageNumberInfo = packages.Select(package =>
            //            {
            //                var packageSplit = package.Split('/');
            //                BaggageNumberInfo_Type baggageNumber = new BaggageNumberInfo_Type();
            //                baggageNumber.BaggageNumber = packageSplit[0];
            //                baggageNumber.TargetCity = packageSplit.Length > 1 ? packageSplit[1] : "";
            //                return baggageNumber;
            //            }).ToArray();

            //            passenger.BoardingCheckNumber = prl.BN;

            //            passenger.BoardingGateNumber = prl.GATE;
            //            passenger.ChineseName = prl.CNIN;
            //            passenger.CKIN = prl.CKIN;
            //            string[] outBounds = prl.OutBound.Trim().Split(new char[] { '\x20' }, StringSplitOptions.RemoveEmptyEntries);
            //            Regex regex = new Regex(@"^(\w{2,3}\d{3,4})([A-Z])(\d{2})([A-Z]{3})$");
            //            passenger.ConnectingFlight = outBounds.Select(outBound => new ConnectingFlight_Type()
            //            {
            //                FlightNumber = regex.Match(outBound).Groups[1].Value,
            //                //FNPostfix = regex.Match(outBound).Groups[2].Value,
            //                Tag = regex.Match(outBound).Groups[2].Value,
            //                DepartureDate =
            //                        new DateTime(DateTime.Now.Year, DateTime.Now.Month
            //                    , int.Parse(regex.Match(outBound).Groups[3].Value)),
            //                ArriveAirport = regex.Match(outBound).Groups[4].Value,
            //            }).ToArray();
            //            Regex foidRegex = new Regex(@"^([A-Z]{2,})(\d+)$");
            //            GroupCollection foidGroups = foidRegex.Match(prl.FOID).Groups;
            //            passenger.FOID = new FOID_Type()
            //            {
            //                RegistrationType = foidGroups.Count > 1 ? foidGroups[1].Value : "",
            //                RegistrationNumber = foidGroups.Count > 1 ? foidGroups[2].Value : "",
            //            };
            //            Regex fqtRegex = new Regex(@"^([A-Z]+)\x20(\d+)\/([A-Z])$");
            //            passenger.FrequentFlyer = prl.FQTV == "" ? null
            //                : new FFPCard_Type()
            //                {
            //                    FFPProgramOwner = fqtRegex.Match(prl.FQTV).Groups[1].Value,
            //                    LoyaltyCardNO = fqtRegex.Match(prl.FQTV).Groups[2].Value,
            //                    CardLevel = fqtRegex.Match(prl.FQTV).Groups[3].Value,
            //                    DelimiterSL = "",
            //                    //Tag=prl.FQTU,
            //                };
            //            passenger.FrequentFlyerRedemption = prl.FQTR == "" ? null
            //                : new FFPCard_Type()
            //            {
            //                FFPProgramOwner = fqtRegex.Match(prl.FQTR).Groups[1].Value,
            //                LoyaltyCardNO = fqtRegex.Match(prl.FQTR).Groups[2].Value,
            //                CardLevel = fqtRegex.Match(prl.FQTR).Groups[3].Value,
            //                DelimiterSL = "",
            //                //Tag=prl.FQTU,
            //            };
            //            passenger.FrequentFlyerUpgrade = prl.FQTS == "" ? null
            //                : new FFPCard_Type()
            //            {
            //                FFPProgramOwner = fqtRegex.Match(prl.FQTS).Groups[1].Value,
            //                LoyaltyCardNO = fqtRegex.Match(prl.FQTS).Groups[2].Value,
            //                CardLevel = fqtRegex.Match(prl.FQTS).Groups[3].Value,
            //                DelimiterSL = "",
            //                //Tag=prl.FQTU,
            //            };
            //            passenger.FrequentFlyerPartneredAirline = prl.FQTU == "" ? null
            //                : new FFPCard_Type()
            //            {
            //                FFPProgramOwner = fqtRegex.Match(prl.FQTU).Groups[1].Value,
            //                LoyaltyCardNO = fqtRegex.Match(prl.FQTU).Groups[2].Value,
            //                CardLevel = fqtRegex.Match(prl.FQTU).Groups[3].Value,
            //                DelimiterSL = "",
            //                //Tag=prl.FQTU,
            //            };
            //            passenger.FullName = new FullName_Type()
            //            {
            //                GivenName = prl.PName.IndexOf('/') != -1 ? prl.PName.Split('/')[1] : prl.PName,
            //                Surname = prl.PName.IndexOf('/') != -1 ? prl.PName.Split('/')[0] : "",
            //            };
            //            passenger.HistoryCabin = prl.HC;
            //            passenger.InfantNumber = (prl.SSR == SSRType.INF1 ? 1 : (prl.SSR == SSRType.INF2 ? 2 : 0)).ToString();
            //            Regex psptRegex = new Regex(@"^HK1\x20(\w+)/([A-Z]+)\/(\w+)/([A-Z]+)(-[A-Z]+)?$");
            //            passenger.Passport = new Passport_Type()
            //            {
            //                PassportNumber = psptRegex.Match(prl.PSPT).Groups[1].Value,
            //                Country = psptRegex.Match(prl.PSPT).Groups[2].Value,
            //                Birthday = psptRegex.Match(prl.PSPT).Groups[3].Value,
            //                Sex = psptRegex.Match(prl.PSPT).Groups[4].Value,
            //                Name = prl.PName,
            //            };
            //            passenger.PNRReference = prl.PNR;
            //            passenger.PreferredTitle = "";
            //            passenger.PSM = prl.PSM;
            //            passenger.SeatNumber = prl.Seat;
            //            Regex shareRegex = new Regex(@"^(\w{2,3}\d{4})([A-Z])(\d{2})([A-Z]{3})(([A-Z]{3})(\d{4})([A-Z]{2})?)?$");
            //            passenger.SharedFlightInfo = prl.ShareCode.Trim().Split(new char[] { '\x20' }, StringSplitOptions.RemoveEmptyEntries)
            //                .Select(shareCode =>
            //                {
            //                    GroupCollection groups = shareRegex.Match(shareCode).Groups;
            //                    if (groups.Count < 2)
            //                        return null;
            //                    SharedFlightInfo_Type shareFlight = new SharedFlightInfo_Type();
            //                    shareFlight.SharedFlightNumber = groups[1].Value;
            //                    //FNPostfix = shareRegex.Match(shareCode).Groups[2].Value,
            //                    shareFlight.SubCarbin = groups[2].Value;
            //                    shareFlight.Day = new DateTime(DateTime.Now.Year, DateTime.Now.Month,
            //                        int.Parse(groups[3].Value.Substring(0, 2))
            //                            );
            //                    shareFlight.DepartureAirport = groups[4].Value;
            //                    if (groups.Count > 5)
            //                    {
            //                        shareFlight.ArriveAirport = groups[6].Value;
            //                        shareFlight.DepartureTime = shareFlight.Day
            //                            .AddHours(int.Parse(groups[7].Value.Substring(0, 2)))
            //                            .AddMinutes(int.Parse(groups[7].Value.Substring(2, 2))).ToUniversalTime();
            //                    }
            //                    return shareFlight;
            //                }).ToArray();
            //            passenger.SpecialMeal = prl.SPML.ToString();
            //            passenger.STCRIndicator = Passenger_TypeSTCRIndicator.Item1;
            //            passenger.STCRIndicatorSpecified = prl.SSR == SSRType.STCR;
            //            passenger.TicketNumber = new string[] { prl.TKNE };
            //            passenger.ChildrenNumber = (prl.SSR == SSRType.CHD1 ? 1 : (prl.SSR == SSRType.CHD2 ? 2 : 0)).ToString();
            //            passenger.BLNDIndicator = Passenger_TypeBLNDIndicator.Item1;
            //            passenger.DEAFIndicator = Passenger_TypeDEAFIndicator.Item1;
            //            passenger.UMIndicator = Passenger_TypeUMIndicator.Item1;
            //            passenger.ID1Indicator = Passenger_TypeID1Indicator.Item1;
            //            passenger.VIPIndicator = Passenger_TypeVIPIndicator.Item1;
            //            passenger.WCBDIndicator = Passenger_TypeWCBDIndicator.Item1;
            //            passenger.VIPIndicatorSpecified = prl.IsVip;
            //            passenger.BLNDIndicatorSpecified = (prl.SSR & SSRType.BLIND) == SSRType.BLIND;
            //            passenger.DEAFIndicatorSpecified = (prl.SSR & SSRType.DEAF) == SSRType.DEAF;
            //            passenger.UMIndicatorSpecified = (prl.SSR & SSRType.UM) == SSRType.UM;
            //            passenger.ID1IndicatorSpecified = (prl.SSR & SSRType.ID1) == SSRType.ID1;
            //            passenger.WCBDIndicatorSpecified = (prl.SSR & SSRType.WCBD) == SSRType.WCBD;
            //            passenger.WCBWIndicatorSpecified = (prl.SSR & SSRType.WCBW) == SSRType.WCBW;
            //            passenger.WCHCIndicatorSpecified = (prl.SSR & SSRType.WCHC) == SSRType.WCHC;
            //            passenger.WCHRIndicatorSpecified = (prl.SSR & SSRType.WCHR) == SSRType.WCHR;
            //            passenger.WCHSIndicatorSpecified = (prl.SSR & SSRType.WCHS) == SSRType.WCHS;
            //            passenger.WCMPIndicatorSpecified = (prl.SSR & SSRType.WCMP) == SSRType.WCMP;
            //            passenger.WCOBIndicatorSpecified = (prl.SSR & SSRType.WCOB) == SSRType.WCOB;
            //        }
            //        #endregion
            //        category.Passenger = passengers.ToArray();

            //        Segment_Type segment = new Segment_Type();
            //        segment.ArriveAirport = prlFlightCabinNoGroup.Key.Substring(0, 3);
            //        segment.PassengersCount = prlFlightCabinNoGroup.Key.Substring(3, 3);
            //        segment.SubCabin = prlFlightCabinNoGroup.Key.Substring(6, 1);

            //        category.Segment = segment;
            //    }
            //    #endregion
            //    prlmessage.PRLData = categories.ToArray();

            //    ESBHeadInfo headinfo = new ESBHeadInfo();
            //    headinfo.ChannelId = "01";
            //    headinfo.CompressionFlag = " ";
            //    headinfo.EncryptionFlag = " ";
            //    headinfo.LogPayloadFlag = "N";
            //    headinfo.NeedRequest = " ";
            //    headinfo.ProcessTimestamp = DateTime.Now.ToString("yyyyMMddhhmmssfff");
            //    headinfo.RequesterId = "0018";
            //    headinfo.ServiceId = "00000000000001";
            //    headinfo.ServiceSn = "100180001" + DateTime.Now.ToString("yyyyMMddhhmmssfff") + "0" + (((snFix - 1.5) * -1) + 1.5).ToString();
            //    headinfo.Status = "S";
            //    headinfo.SystemId = "0018";
            //    headinfo.TimeOut = " ";
            //    headinfo.UserId = " ";
            //    headinfo.Password = " ";
            //    headinfo.VersionId = "01";


            //    //ESBTMPPPRLServiceRequest request = new ESBTMPPPRLServiceRequest();
            //    //request.ESBHeader = headinfo;
            //    //request.ESBTMPPPRLService = esbService;

            //    //ESBTMPPRPLServiceClient epsClient = new ESBTMPPRPLServiceClient();

            //    ESBTMPPPRLService service = new ESBTMPPPRLService();
            //    service.ESBHeader = headinfo;
            //    //service.CallESBTMPPPRLServiceCompleted += new CallESBTMPPPRLServiceCompletedEventHandler(service_CallESBTMPPPRLServiceCompleted);
            //    //service.CallESBTMPPPRLServiceAsync(esbService);
            //    try
            //    {
            //        ESBTMPPPRLServiceResponse response = service.CallESBTMPPPRLService(esbService);
            //        if (response.PRLResult.ESBStdReturnInfo.Code == "")
            //        {

            //        }
            //    }
            //    catch (Exception ex)
            //    {

            //        throw;
            //    }


            //    //ESBTMPPRPLServiceClient epsClient = new ESBTMPPRPLServiceClient();


            //    //try
            //    //{

            //    //    ESBTMPPPRLServiceResponse response = epsClient.ESBTMPPPRLService(ref headinfo, esbService);
            //    //    if (response.PRLResult.ESBStdReturnInfo.Code == "1000")
            //    //    {

            //    //    }

            //    //}
            //    //catch (System.ServiceModel.FaultException ex)
            //    //{

            //    //    throw ex;
            //    //}
            //}

            //foreach (DCSFile file in DCSFileList)
            //{
            //    UpDCSFileStatus(file.FileId);
            //}
		}

		private bool batchUpdateDCSFileStatus(List<DCSFile> files)
		{
			string fileIds = string.Join(",", files.Select(f => f.FileId.ToString()).ToArray());
			using (SqlConnection conn = GetSqlConnection())
			{
				long el = SqlHelper.ExecuteNonQuery(conn, "up_BatchUpdateDCSFileStatus",
						new SqlParameter("@fileIds", fileIds)
					);
				return el == files.Count;
			}
		}

		private void UpDCSFileStatus(int fileId)
		{
			string sqltext = "UPDATE [DCSFile] SET [Status] = 256;";
			using (SqlConnection conn = GetSqlConnection())
			{
				SqlHelper.ExecuteNonQuery(conn, sqltext);
			}
		}

		void service_CallESBTMPPPRLServiceCompleted(object sender, CallESBTMPPPRLServiceCompletedEventArgs e)
		{


			throw new NotImplementedException();
		}

		private static string connectionString;


		IEnumerable<PRLMessage> getPRLMessages()
		{
			connectionString = ConfigurationManager.ConnectionStrings["DCSDB"].ConnectionString;




			return null;
		}

		private SqlConnection GetSqlConnection()
		{
			return new SqlConnection(connectionString);
		}
	}
}


namespace DCS.DemoWinApp.TMPP_PRL_Interface
{
	public partial class Flight_Type
	{
		public override bool Equals(object obj)
		{
			if (!(obj is Flight_Type)) return false;
			else
			{
				Flight_Type flight = obj as Flight_Type;
				return this.DepartureDate == flight.DepartureDate
					&& this.FlightNumber == flight.FlightNumber
					&& this.DepartureAirport == flight.DepartureAirport
					&& this.FNPostfix == flight.FNPostfix;
			}
		}

		public override int GetHashCode()
		{
			return 0;
		}
	}

}
